package com.tidc.seaserverservice.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tidc.seaservermapper.dao.*;
import com.tidc.seaservermodel.config.RabbitConfig;
import com.tidc.seaservermodel.config.RabbitConstants;
import com.tidc.seaservermodel.entity.*;
import com.tidc.seaserverservice.service.RabbitService;
import com.tidc.seaserverservice.util.RabbitUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

/**
 * @author ：冯涛滔
 * @date ：Created in 2020/10/5 11:16
 * @description：
 * @modified By：
 * @version:
 */
@Service
@Slf4j
public class RabbitServiceImpl implements RabbitService {
    @Resource
    private TaskDao taskDao;
    @Resource
    private UserTaskDao userTaskDao;
    @Resource
    private UserDao userDao;
    @Resource
    private EmailDao emailDao;
    @Resource
    private CommitmentDao commitmentDao;
    @Resource
    private RabbitMessageLogDao rabbitMessageLogDao;
    @Resource
    private ObjectMapper objectMapper;
    @Resource
    private RabbitUtil rabbitUtil;

    @Override
    public Fres<Integer> seaAddExperience(UserTask userTask) throws SQLException {
        Task task = taskDao.queryById(userTask.getTaskId());
        userTask = userTaskDao.queryById(userTask.getId());
        userDao.addExperience(task.getAwardLevel(), task.getAwardMoney(), userTask.getUserId());
        return Fres.Success();
    }

    @Override
    public Fres<Integer> punishmentExperience(UserTask userTask) throws SQLException {
        userTask = userTaskDao.queryById(userTask.getId());
        Task task = taskDao.queryById(userTask.getTaskId());
        User user = userDao.getUser(userTask.getUserId());
        //        levelValue 有毛病
//        TODO 改userDao
        user.setLevelValue(Math.max(user.getLevelValue() - task.getPunishmentLevel(), 0));
        user.setMoney(Math.max(user.getMoney() - task.getPunishmentMoney(), 0));
        userDao.update(user);
        return Fres.Success();
    }

    @Override
    public Fres<Integer> seaAddEmail(Email email) {
        emailDao.insert(email);
        return Fres.Success();
    }

    @Transactional
    @Override
    public Fres<Integer> seaTaskCheckTimeout(UserTask userTask) throws JsonProcessingException {
        userTask = userTaskDao.queryById(userTask.getId());
        User user = userDao.queryById(userTask.getUserId());
        Task task = taskDao.queryById(userTask.getTaskId());
//        没完成直接给他挂了
        if (userTask.getFinishTime() == null) {
            userTaskDao.finishTask(userTask.getId(), 2,null);
            if (task.getTypeClassify() == 2) {
                task.setIsDelete(1);
                taskDao.update(task);
            }
            Email sendSupervisorEmail = Email.sendSupervisorTaskOverdue(user.getName(), task.getName(), user.getSuperiorUserId());
            Email sendSecondaryEmail = Email.sendSecondaryTaskOverdue(task.getName(), userTask.getUserId());
            RabbitMessageLog sendSecondaryRm = RabbitMessageLog.sendEmail(objectMapper.writeValueAsString(sendSecondaryEmail));
            RabbitMessageLog sendSupervisorRm = RabbitMessageLog.sendEmail(objectMapper.writeValueAsString(sendSupervisorEmail));
            RabbitMessageLog punishmentExperience = RabbitMessageLog.punishmentExperience(objectMapper.writeValueAsString(userTask));
            rabbitUtil.sendMQ(punishmentExperience);
            rabbitUtil.sendMQ(sendSecondaryRm);
            rabbitUtil.sendMQ(sendSupervisorRm);
        }
        return Fres.Success();
    }

    @Override
    public Fres<Integer> seaCheckCommitmentOut(Commitment commitment) {
        commitment = commitmentDao.queryById(commitment.getId());
//        超时而且未完成
        if (commitment.getStatusType() == 0) {
            commitmentDao.setTimeOut(commitment.getId());
        }
        return Fres.Success();
    }

    @Override
    public Fres<Integer> clearRabbit(RabbitMessageLog rabbitMessageLog) {
        List<RabbitMessageLog> list = rabbitMessageLogDao.queryAllByLimit(0, 100);
        for (RabbitMessageLog messageLog : list) {
            if (messageLog.getCount() >= RabbitConstants.MAX_TRY_COUNT) {
                rabbitMessageLogDao.updateLogStatus(RabbitConstants.FAILURE, rabbitMessageLog.getMsgId());
            } else {
                long time = new Date().getTime();
                if (!messageLog.getTryTime().before(new Timestamp(time))) {
                    break;
                }
                //十分钟后重试
                rabbitMessageLog.setTryTime(new Timestamp(time + (1000 * 60 * 10)));
                rabbitMessageLogDao.addCount(messageLog.getMsgId(), messageLog.getTryTime());
                rabbitUtil.sendMQ(messageLog);
            }
        }
        return Fres.Success();
    }
}
